package com.tlkj.common.curd.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.tlkj.common.curd.entity.Api;
import com.tlkj.common.curd.entity.ApiParams;
import com.tlkj.common.curd.mapper.ApiMapper;
import com.tlkj.common.curd.mapper.ApiParamsMapper;
import com.tlkj.common.curd.service.ApiService;
import com.tlkj.common.curd.util.PageUtil;
import com.tlkj.common.curd.vo.ApiVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author flyong86
 */
@Service
@RequiredArgsConstructor
public class ApiServiceImpl implements ApiService {

    private final ApiMapper apiMapper;
    private final ApiParamsMapper apiParamsMapper;

    @Override
    public Api queryById(String id) {
        return apiMapper.queryById(id);
    }

    @Override
    public PageInfo<Api> page(Page<Api> page, Api api) {
//        PageHelper.startPage(page.getPageNum(), page.getPageSize());

        int total = apiMapper.queryCount(api);
//        try (SqlSession sqlSession = sessionFactory.openSession()) {
//            count = PageHelper.count(sqlSession.selectOne("com.tlkj.common.curd.mapper.ApiMapper.queryAllByLimit", api));
//        }

        if (total > 0) {
            List<Api> list = apiMapper.queryAllByLimit(api, page.getStartRow(), page.getPageSize());

            // 分页返回分页对象
            PageInfo<?> pageInfo = new PageInfo<>(list);
            pageInfo.setPageNum(page.getPageNum());
            pageInfo.setPageSize(page.getPageSize());
            pageInfo.setTotal(total);
            pageInfo.setPages((int) Math.ceil((double) pageInfo.getTotal() / pageInfo.getPageSize()));
//            return new PageInfo<>(list, page.getPageNum());
            return PageUtil.pageInfo(page.getPageNum(), page.getPageSize(), total, list);
        } else {
            return PageInfo.emptyPageInfo();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(ApiVo api) throws Exception {

        // 检测PATH是否存在
        Api existApi = apiMapper.selectByPath(api.getPath(), null);
        if (existApi != null) {
            throw new Exception("接口地址已存在!");
        }

        String id = IdUtil.getSnowflakeNextId() + "";
        api.setId(id);
        apiMapper.insert(api);

        // 请求参数
        List<ApiParams> requestParams = api.getRequestParams();
        if (requestParams != null && !requestParams.isEmpty()) {
            requestParams.forEach(item -> {
                item.setApiId(id);
                item.setId(IdUtil.getSnowflakeNextId() + "");

                if (item.getField() == null || item.getField().isEmpty()) {
                    item.setField(item.getName());
                }
                item.setParamType(ApiParams.ParamType.REQUEST.getVal());
            });

            apiParamsMapper.insertBatch(requestParams);
        }

        // 返回参数
        List<ApiParams> returnParams = api.getReturnParams();
        if (returnParams != null && !returnParams.isEmpty()) {
            returnParams.forEach(item -> {
                item.setApiId(id);
                item.setId(IdUtil.getSnowflakeNextId() + "");
                item.setParamType(ApiParams.ParamType.RETURN.getVal());
                item.setRequired(item.getRequired() != null && item.getRequired());

            });

            apiParamsMapper.insertBatch(returnParams);
        }
    }

    @Override
    public void update(ApiVo api) throws Exception {
        // 检测PATH是否存在
        Api existApi = apiMapper.selectByPath(api.getPath(), null);
        if (existApi != null && !existApi.getPath().equals(api.getPath())) {
            throw new Exception("接口地址已存在!");
        }

        apiMapper.update(api);

        // 清除所有的参数
        apiParamsMapper.deleteByApi(api.getId());

        // 请求参数
        List<ApiParams> requestParams = api.getRequestParams();
        if (requestParams != null && !requestParams.isEmpty()) {
            requestParams.forEach(item -> {
                item.setApiId(api.getId());
                item.setId(IdUtil.getSnowflakeNextId() + "");
                item.setParamType(ApiParams.ParamType.REQUEST.getVal());
                item.setRequired(item.getRequired() != null && item.getRequired());

                if (item.getField() == null || item.getField().isEmpty()) {
                    item.setField(item.getName());
                }

            });

            apiParamsMapper.insertBatch(requestParams);
        }

        // 返回参数
        List<ApiParams> returnParams = api.getReturnParams();
        if (returnParams != null && !returnParams.isEmpty()) {
            returnParams.forEach(item -> {
                item.setApiId(api.getId());
                item.setId(IdUtil.getSnowflakeNextId() + "");
                item.setParamType(ApiParams.ParamType.RETURN.getVal());

            });

            apiParamsMapper.insertBatch(returnParams);
        }
    }

    @Override
    public boolean deleteById(String id) {
        apiMapper.deleteById(id);
        return true;
    }

    @Override
    public ApiVo findInfo(String id) {

        Api api = apiMapper.queryById(id);
        if (null != api) {

            ApiVo apiVo = new ApiVo();
            BeanUtil.copyProperties(api, apiVo);

            List<ApiParams> params = apiParamsMapper.findByApiId(id);
            if (null != params && !params.isEmpty()) {
                // 筛选出请求参数
                List<ApiParams> requestParams = params.stream()
                        .filter(item -> item.getParamType().equals(ApiParams.ParamType.REQUEST.getVal()))
                        .collect(Collectors.toList());

                apiVo.setRequestParams(requestParams);

                // 筛选出返回参数
                List<ApiParams> returnParams = params.stream()
                        .filter(item -> item.getParamType().equals(ApiParams.ParamType.RETURN.getVal()))
                        .collect(Collectors.toList());

                apiVo.setReturnParams(returnParams);
            }
            return apiVo;
        }
        return null;
    }

    @Override
    public ApiVo findByPath(String path, Boolean enable) {
        Api api = apiMapper.selectByPath(path, enable);
        if (api == null) {
            return null;
        }

        ApiVo apiVo = new ApiVo();
        BeanUtil.copyProperties(api, apiVo);

        List<ApiParams> params = apiParamsMapper.findByApiId(api.getId());
        if (null != params && !params.isEmpty()) {
            // 筛选出请求参数
            List<ApiParams> requestParams = params.stream()
                    .filter(item -> item.getParamType().equals(ApiParams.ParamType.REQUEST.getVal()))
                    .collect(Collectors.toList());

            apiVo.setRequestParams(requestParams);

            // 筛选出返回参数
            List<ApiParams> returnParams = params.stream()
                    .filter(item -> item.getParamType().equals(ApiParams.ParamType.RETURN.getVal()))
                    .collect(Collectors.toList());

            apiVo.setReturnParams(returnParams);
        }
        return apiVo;
    }
}
